﻿using System.Security.Claims;
using JwtBearerDemo.Config;
using JwtBearerDemo.Model;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;

namespace JwtBearerDemo.JwtHelper;

public static class JwtHelper {
    public static UserInfo Account (this ControllerBase c) {
        return new UserInfo
        {
            ID = c.User.FindFirst("user_id")?.Value,
            Group = c.User.FindFirst("user_group")?.Value,
            Name = c.User.FindFirst("user_name")?.Value,
            Organization = c.User.FindFirst("organization")?.Value,
            Role = c.User.FindFirst(ClaimTypes.Role)?.Value,
            Phone = c.User.FindFirst(ClaimTypes.MobilePhone)?.Value,
            Gender = c.User.FindFirst(ClaimTypes.Gender)?.Value,
            Surname = c.User.FindFirst(ClaimTypes.Surname)?.Value,
            Email = c.User.FindFirst(ClaimTypes.Email)?.Value
        };
    }


    /// <summary>
    /// Jwt鉴权
    /// </summary>
    public static void JwtBearer (this IServiceCollection services) {
        services.AddAuthentication(options => {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options => {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,                      // 是否验证超时(当设置exp和nbf时有效)
                ValidateIssuerSigningKey = true,              // 是否验证密钥

                ValidAudience = MyConfig.Adu,
                ValidIssuer = MyConfig.Iss,
                IssuerSigningKey = new SymmetricSecurityKey(MyConfig.Key),
                ClockSkew = TimeSpan.FromMinutes(0)   // 过期缓冲时间(expire+skew,默认5分钟)
            };

            options.Events = new JwtBearerEvents
            {
                //此处为权限验证失败后触发的事件
                OnChallenge = context => {
                    context.HandleResponse();                    //跳过默认逻辑
                    context.Response.ContentType = "application/json;charset=utf-8";
                    //context.Response.StatusCode = StatusCodes.Status200OK;
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;

                    var payload = JsonConvert.SerializeObject(new { code = 0, message = "invalid token" });
                    context.Response.WriteAsync(payload);
                    return Task.FromResult(0);
                }
            };
        });
    }
}
